<?php


class sc2Parser
{

	private static $nullProfile = array (
		'account' => array (
			'name' => null
			),
		'portrait' => array (
			'url' => null,
			'x' => null, 'y' => null, 'w' => null, 'h' => null
			),
		'clan' => array (
			'name' => null,
			'tag' => null
			),
		'1v1' => array (
			'race' => null,
			'league' => null,
			'rank' => null,
			'points' => null,
			'wins' => null,
			'losses' => null
			)
		);

	private $profile;

	private function reset_array (&$array) {
		/*foreach ($array as &$key) {
			if (is_array($key)) {
				$this->reset_array ($key);
			}
			else {
				$key = null;
			}
		}*/
		$array = self::$nullProfile;
	}

	private function reset_profile () {
		$this->reset_array ($this->profile);
	}


	function simpleRegEx ($pattern, $subject) {
		preg_match($pattern, $subject, $result);
		return $result[1];
	}

	/*
	 * Parse a HTML source code and returns an array with the desired data.
	 */
	public function parseHTML ($htmlSource, &$profile = null) {

		static $htmlQueries = '
			//*[@id="profile-header"]/h2/span |
			//*[@id="portrait"]/span |
			//*[@id="portrait-frame"] |
			//*[@id="current-rank"]/td
			';

		static $rgNum = "[+-]?\d+";
		$pattern = array (
			'portrait' => "#.*url\('(.*)'\).*?($rgNum)px.*?($rgNum)px.*?($rgNum)px.*?($rgNum)px;#",
			'clan' => "#\[(\w*?)\]\s+(.*)#",
			'race' => "#race-(\w*)#",
			'league' => "#portrait-border-(\w*)#",
			'rank' => "#(\d+)#"
			);

		$isNullProfile = ($profile === null);
		if ($isNullProfile) {
			$this->reset_profile();
			$profile = &$this->profile;
		}

		$htmlDOM = new DOMDocument;
		$htmlDOM->loadHTML ($htmlSource);
		$htmlXPath = new DOMXPath ($htmlDOM);
		$htmlQueryResult = $htmlXPath->query ($htmlQueries);

		// Getting user name.
		$name = $htmlQueryResult->item(2)->lastChild->previousSibling->nodeValue;
		$profile['account']['name'] = trim($name);
		// Getting portrait info.
		$portrait = $htmlQueryResult->item(0)->getAttribute('style');
		preg_match ($pattern['portrait'], $portrait, $portraitInfo);
		$profile['portrait']['url'] = $portraitInfo[1];
		$profile['portrait']['x'] = $portraitInfo[2];
		$profile['portrait']['y'] = $portraitInfo[3];
		$profile['portrait']['w'] = $portraitInfo[4];
		$profile['portrait']['h'] = $portraitInfo[5];


		if ($htmlQueryResult->length > 3) {

			$l = 3;
	
			if ($htmlQueryResult->item(3)->tagName == 'span') {
				++$l;
				// Getting clan name and clan tag.
				$clan = $htmlQueryResult->item(3)->nodeValue;
				preg_match ($pattern['clan'], $clan, $clanInfo);
				$profile['clan']['name'] = $clanInfo[2];
				$profile['clan']['tag'] = $clanInfo[1];
			}
			else if (! $isNullProfile) {
				$profile['clan'] = self::$nullProfile['clan'];
			}
	
			if ($htmlQueryResult->length > 4) {
				// Getting favorite race.
				if (! method_exists($htmlQueryResult->item($l+2)->firstChild->nextSibling, 'getAttribute')) {
					++$l;
				}
				$race = $htmlQueryResult->item($l+2)->firstChild->nextSibling->getAttribute('class');
				$profile['1v1']['race'] = $this->simpleRegEx($pattern['race'], $race);
				// Getting league.
				$league = $htmlQueryResult->item(1)->getAttribute('class');
				$profile['1v1']['league'] = $this->simpleRegEx($pattern['league'], $league);
				// Getting current rank.
				$rank = $htmlQueryResult->item($l+1)->nodeValue;
				$profile['1v1']['rank'] = $this->simpleRegEx($pattern['rank'], $rank);
				// Getting number of points.
				$points = $htmlQueryResult->item($l+3)->nodeValue;
				$profile['1v1']['points'] = $points;
				// Getting number of wins.
				$wins = $htmlQueryResult->item($l+4)->nodeValue;
				$profile['1v1']['wins'] = $wins;
				// Getting number of losses.
				$losses = $htmlQueryResult->item($l+5)->nodeValue;
				$profile['1v1']['losses'] = $losses;
			}
			else if (! $isNullProfile) {
				$profile['1v1'] = self::$nullProfile['1v1'];
			}
		}
		else if (! $isNullProfile) {
			$profile['clan'] = self::$nullProfile['clan'];
			$profile['1v1'] = self::$nullProfile['1v1'];
		}

		if ($isNullProfile) {
			return $this->profile;
		}
	}

	/*
	 * Parse a JSON source code and returns an array with the desired data.
	 */
	/* NOT IMPLEMENTED YET!
	public function parseJSON ($jsonSource) {
		$this->reset_profile();
		return $this->profile;
	}*/


	/*
	 * Returns the current state of the profile.
	 */
	public function getProfile () {
		return $this->profile;
	}

}


?>